﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace LogParserEx
{
    public partial class Form1 : Form
    {
        #region Attributes

        private string DefaulttabPageName = "SQL";
        private string DefaultRichTextBoxName = "rtbSQL";
        private int count = 1;

        private Thread myThread = null;
        private delegate void myDeleGateDataGridViewOutput(DataTable dt);
        private delegate string myDeleGategetComboBox();
        private delegate string myDeleGategetRichTextBox();
        private delegate void myDeleGateSetStatus(bool b, string s);
        private delegate void myDeleGateShowErr(string s, int i);
        private delegate void myDeleGateShowMsg(Result s, int i);

        #endregion

        #region Form

        public Form1()
        {
            InitializeComponent();
            this.statusStrip1.BackColor = mySet.aeroColor;
            InitComboBox();            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.tabControlSQL.TabPages[0].Name = DefaulttabPageName + count;
            this.tabControlSQL.TabPages[0].Text = DefaulttabPageName + count;
            this.tabControlSQL.TabPages[0].Tag = count;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            if (myThread == null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行查询，确认要强制关闭吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }
            e.Cancel = false;
        }

        protected override void OnLoad(EventArgs e)
        {
            try
            {
                if (System.Environment.OSVersion.Version.Major >= 6)
                {
                    if (SafeNativeMethods.DwmIsCompositionEnabled())
                    {
                        MARGINS margins = new MARGINS();
                        margins.Right = margins.Left = margins.Top = margins.Bottom = -1;   //设为负数,则全窗体透明
                        SafeNativeMethods.DwmExtendFrameIntoClientArea(this.Handle, ref margins);
                    }
                }
                base.OnLoad(e);
            }
            catch
            {
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            try
            {
                base.OnPaintBackground(e);
                if (System.Environment.OSVersion.Version.Major >= 6)
                {
                    if (SafeNativeMethods.DwmIsCompositionEnabled())
                    {
                        e.Graphics.Clear(Color.Black);    //将窗体用黑色填充（Dwm会把黑色视为透明区域）                        
                        this.TransparencyKey = mySet.aeroColor;
                        this.BackColor = mySet.aeroColor;
                        this.menuStrip1.BackColor = mySet.aeroColor;
                    }
                }
            }
            catch
            {
            }
        }

        #endregion

        #region Event

        #region toolStripMenuItem

        #region File

        private void toolStripMenuItem_New_Click(object sender, EventArgs e)
        {
            count++;
            TabPage tabPage = new TabPage();
            tabPage.Name = DefaulttabPageName + count.ToString();
            tabPage.Text = DefaulttabPageName + count.ToString();

            RichTextBox rtbSQL = new RichTextBox();
            rtbSQL.Name = DefaultRichTextBoxName + count.ToString();
            rtbSQL.BorderStyle = BorderStyle.None;
            rtbSQL.Dock = DockStyle.Fill;
            rtbSQL.Font = new System.Drawing.Font("Georgia", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            rtbSQL.KeyDown+=new KeyEventHandler(rtbSQL_KeyDown);
            tabPage.Controls.Add(rtbSQL);

            this.tabControlSQL.TabPages.Add(tabPage);
            this.tabControlSQL.SelectTab(tabPage);
        }

        private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
        {
            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            string txtFileName = null;
            try
            {
                myOpenFileDialog.Filter = "LogParser Explorer files (*.lpe)|*.lpe|AllFiles (*.*)|*.*";
                if (DialogResult.Cancel == myOpenFileDialog.ShowDialog())
                {
                    return;
                }

                txtFileName = myOpenFileDialog.FileName;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                myOpenFileDialog.Dispose();
            }

            toolStripMenuItem_New_Click(sender, e);

            OpenLpe(txtFileName);
        }

        private void toolStripMenuItem_Save_Click(object sender, EventArgs e)
        {
            string txtFileName = ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Tag == null ? "" : ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Tag.ToString();
            string tabPageName = (this.tabControlSQL.SelectedTab.Tag == null || string.IsNullOrEmpty(this.tabControlSQL.SelectedTab.Tag.ToString()) || this.tabControlSQL.SelectedTab.Tag.ToString() == "1") ? this.tabControlSQL.SelectedTab.Text : this.tabControlSQL.SelectedTab.Text.Remove(this.tabControlSQL.SelectedTab.Text.Length - 1);

            if (string.IsNullOrEmpty(txtFileName) || !File.Exists(txtFileName))
            {
                SaveFileDialog mySaveFileDialog = new SaveFileDialog();
                try
                {
                    mySaveFileDialog.ValidateNames = true;
                    mySaveFileDialog.Filter = "LogParser Explorer files (*.lpe)|*.lpe|AllFiles (*.*)|*.*";
                    mySaveFileDialog.AddExtension = true;
                    mySaveFileDialog.FilterIndex = 1;
                    mySaveFileDialog.DefaultExt = "lpe";
                    mySaveFileDialog.FileName = tabPageName + ".lpe";

                    if (mySaveFileDialog.ShowDialog() == DialogResult.Cancel) return;
                    txtFileName = mySaveFileDialog.FileName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    mySaveFileDialog.Dispose();
                }
            }

            SaveLpe(txtFileName);
        }

        private void toolStripMenuItem_Close_Click(object sender, EventArgs e)
        {
            if (this.tabControlSQL.SelectedTab.Tag != null && !string.IsNullOrEmpty(this.tabControlSQL.SelectedTab.Tag.ToString()) && this.tabControlSQL.SelectedTab.Tag.ToString() != "1")
            {
                toolStripMenuItem_Save_Click(sender, e);
            }
            this.tabControlSQL.Controls.Remove(this.tabControlSQL.SelectedTab);
        }

        private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion

        #region Edit

        private void toolStripMenuItem_Undo_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Undo();
        }

        private void toolStripMenuItem_Redo_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Redo();
        }

        private void toolStripMenuItem_Cut_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Cut();
        }

        private void toolStripMenuItem_Copy_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Copy();
        }

        private void toolStripMenuItem_Paste_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Paste();
        }

        private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
        {
            ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).SelectAll();
        }

        private void toolStripMenuItem_Font_Click(object sender, EventArgs e)
        {
            FontDialog myFontDialog = new FontDialog();
            myFontDialog.ShowEffects = false;
            myFontDialog.Font = this.rtbSQL1.Font;
            if (myFontDialog.ShowDialog() == DialogResult.Cancel) return;
            foreach (TabPage tp in this.tabControlSQL.TabPages)
            {
                tp.Controls[0].Font = myFontDialog.Font;
            }

        }

        #endregion

        #region SQL

        private void toolStripMenuItem_RunSQL_Click(object sender, EventArgs e)
        {
            if (this.toolStripComboBox_FileType.SelectedItem == null)
            {
                MessageBox.Show("请选择输入文件类型");
                return;
            }

            SetStatus(false, "正在进行查询，请稍后……");

            myThread = new Thread(new ThreadStart(ThreadLog));
            myThread.Start();
        }

        private void toolStripMenuItem_StopSQL_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive)
            {
                myThread.Abort();
            }
            
            SetStatus(true, "用户终止操作");
        }

        #endregion

        #region Help

        private void toolStripMenuItem_About_Click(object sender, EventArgs e)
        {
            MessageBox.Show("LogParser Exlorer");
        }

        #endregion

        #endregion

        #region toolStrip

        private void toolStripButton_New_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_New_Click(sender, e);
        }

        private void toolStripButton_Open_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Open_Click(sender, e);
        }

        private void toolStripButton_Save_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_Save_Click(sender, e);
        }

        private void toolStripButton_Check_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_RunSQL_Click(sender, e);
        }

        private void toolStripButton_Stop_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_StopSQL_Click(sender, e);
        }

        private void toolStripButton_Info_Click(object sender, EventArgs e)
        {
            toolStripMenuItem_About_Click(sender, e);
        }

        #endregion

        #region TabControl

        private void tabControlSQL_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left) toolStripMenuItem_Close_Click(sender, e);
        }

        #endregion

        #region RichTextBox

        private void rtbSQL_KeyDown(object sender, KeyEventArgs e)
        {
            if (this.tabControlSQL.SelectedTab.Tag == null || string.IsNullOrEmpty(this.tabControlSQL.SelectedTab.Tag.ToString()) || this.tabControlSQL.SelectedTab.Tag.ToString() == "1")
            {
                this.tabControlSQL.SelectedTab.Text += "*";
                this.tabControlSQL.SelectedTab.Tag = "0";
            }
        }

        #endregion

        #endregion

        #region Thread

        private void ThreadLog()
        {
            Log myLog = null;
            Result res = new Result();
            try
            {
                myLog = new Log(getComboBox(), getRichTextBox().ToLower().Replace("from", "into dgvResult from"));

                DataTable dt = myLog.getData();
                DataGridViewOutput(dt);
                res = myLog.myResult;
                ShowMsg(res, 0);
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                ShowErr(ex.Message + ex.GetType().ToString(), 1);
            }
            finally
            {
                SetStatus(true, "查询完成");
            }
        }

        #endregion

        #region Method

        private void DataGridViewOutput(DataTable dt)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateDataGridViewOutput(DataGridViewOutput), new object[] { dt });

            }
            else
            {
                this.dgvResult.DataSource = dt;
            }
        }

        private string getComboBox()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetComboBox(getComboBox)) as string;

            }
            else
            {
                return this.toolStripComboBox_FileType.SelectedItem.ToString();
            }
        }

        private string getRichTextBox()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetRichTextBox(getRichTextBox)) as string;
            }
            else
            {
                string rval = "";
                if (((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).SelectedText.Length == 0) rval = ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Text;
                else rval = ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).SelectedText;
                return rval;
            }
        }

        private void SetStatus(bool b,string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetStatus(SetStatus), new object[] { b, s });
            }
            else
            {
                try
                {
                    this.toolStripButton_Check.Enabled = b;
                    this.toolStripMenuItem_RunSQL.Enabled = b;
                    this.toolStripButton_Stop.Enabled = !b;
                    this.toolStripMenuItem_StopSQL.Enabled = !b;
                    this.tsslMsg.Text = s+DateTime.Now.ToLongTimeString();
                    this.tssling.Visible = !b;
                }
                catch (ThreadAbortException)
                {
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void ShowErr(string s, int i)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateShowErr(ShowErr), new object[] { s, i });
            }
            else
            {
                this.rtbMessage.Text = s;
                this.tabControlResult.SelectedIndex = i;
            }
        }

        private void ShowMsg(Result res, int i)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateShowMsg(ShowMsg), new object[] { res, i });
            }
            else
            {
                this.rtbMessage.Text = string.Format("查询完成。\n共检索到{0}条记录。\n查询耗时：{1}。\n显示耗时：{2}。", res.number, res.sqlTime, res.displayTime);
                this.tabControlResult.SelectedIndex = i;
            }
        }

        private void InitComboBox()
        {
            this.toolStripComboBox_FileType.Items.Add("ADS");
            this.toolStripComboBox_FileType.Items.Add("BIN");
            this.toolStripComboBox_FileType.Items.Add("COM");
            this.toolStripComboBox_FileType.Items.Add("CSV");
            this.toolStripComboBox_FileType.Items.Add("ETW");
            this.toolStripComboBox_FileType.Items.Add("EVT");
            this.toolStripComboBox_FileType.Items.Add("FS");
            this.toolStripComboBox_FileType.Items.Add("HTTPERR");
            this.toolStripComboBox_FileType.Items.Add("IIS");
            this.toolStripComboBox_FileType.Items.Add("IISMSID");
            this.toolStripComboBox_FileType.Items.Add("IISODBC");
            this.toolStripComboBox_FileType.Items.Add("IISW3C");
            this.toolStripComboBox_FileType.Items.Add("NCSA");
            this.toolStripComboBox_FileType.Items.Add("NETMON");
            this.toolStripComboBox_FileType.Items.Add("REG");
            this.toolStripComboBox_FileType.Items.Add("TEXTLINE");
            this.toolStripComboBox_FileType.Items.Add("TEXTWORD");
            this.toolStripComboBox_FileType.Items.Add("TSV");
            this.toolStripComboBox_FileType.Items.Add("URLSCAN");
            this.toolStripComboBox_FileType.Items.Add("W3C");
            this.toolStripComboBox_FileType.Items.Add("XML");
        }

        private void SaveLpe(string filePath)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                doc.AppendChild(dec);
                //创建一个根节点（一级）
                XmlElement root = null;
                root=doc.CreateElement("LogParserEx");
                doc.AppendChild(root);

                XmlElement xe = null;

                xe=doc.CreateElement("type");
                xe.InnerText = this.toolStripComboBox_FileType.SelectedItem.ToString();
                root.AppendChild(xe);

                xe = doc.CreateElement("sql");
                xe.InnerText = ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Text;
                root.AppendChild(xe);

                doc.Save(filePath);                 
                MessageBox.Show("保存成功");

                ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Tag = filePath;
                this.tabControlSQL.SelectedTab.Tag = "1";
                string[] txtFilePath = filePath.Split('\\');
                this.tabControlSQL.SelectedTab.Text = txtFilePath[txtFilePath.Length - 1];
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void OpenLpe(string filePath)
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(filePath);

                XmlNode root=doc.SelectSingleNode("LogParserEx");

                XmlNode node = null;

                node=root.SelectSingleNode("type");
                this.toolStripComboBox_FileType.SelectedItem = node.InnerText;

                node = root.SelectSingleNode("sql");
                ((RichTextBox)(this.tabControlSQL.SelectedTab.Controls[0])).Text = node.InnerText;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                
            }
        }

        #endregion
    }

    [SuppressUnmanagedCodeSecurity]
    internal static class SafeNativeMethods
    {
        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS margins);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        public static extern bool DwmIsCompositionEnabled();
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct MARGINS
    {
        public int Left;
        public int Right;
        public int Top;
        public int Bottom;
    }

    public class mySet
    {
        public static Color aeroColor = Color.FromArgb(164, 212, 211);
        public static Color percentColor = Color.FromArgb(255, 40, 60, 82);
    } 
}
